from django.views import View
from meiduo_mall.libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from django import http
from meiduo_mall.utils.response_code import RETCODE
from random import randint
# from celery_tasks.sms.yuntongxun import CCP
from celery_tasks.sms.tasks import send_sms_code
import logging
# Create your views here.
# ??
logger = logging.getLogger('django')

class ImageCodeView(View):
    def get(self, request, uuid):
        """
        :param request: 请求对象
        :param uuid: 唯一标识图形验证码所属于的用户
        :return: image/jpg
        """
        # 生成图片验证码 text:验证码内容， image:图片二进制
        name, text, image = captcha.generate_captcha()

        #  创建redis连接对象  verify_code对应setting里2号redis库
        redis_conn = get_redis_connection('verify_code')
        # 保存图片验证码 设置存储key time value
        redis_conn.setex('img_%s' % uuid, 300, text)


        # 响应图片验证码
        return http.HttpResponse(image, content_type='image/jpg')


class SMSCodeView(View):
    # 前端传入参数有: mobile(url传入,正则匹配获取), (image_code, uuid,/?参数形式传入，request对象获取).
    # 需要返回给前端发 短信码

    def get(self, request, mobile, ):
        # 提取参数
        mobile = mobile
        image_code_client = request.GET.get('image_code')
        uuid = request.GET.get('uuid')
        # 创建redis连接对象
        redis_conn = get_redis_connection('verify_code')
        # 获取手机flag,为1说明发过短信了
        flag_mobile = redis_conn.get('flag_%s' % mobile)
        if flag_mobile:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '频繁发送短信'})

        # 校验参数
        if all([image_code_client, uuid]) is False:
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})

        # 提取服务端图形验证码
        image_code_server = redis_conn.get('img_%s' % uuid)
        # 删除验证码，让它只能用一次
        redis_conn.delete('img_%s' % uuid)
        # 注意1.从redis读取的可能为空，返回None, 2.有值都是二进制值 3.值还有可能是大小写混合的
        if image_code_server is None:
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码错误'})

        if image_code_client.lower() != image_code_server.decode().lower():
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码错误'})

        # 发送短信：
        # 1.生成6位数的短信码
        sms_code = '%06d' % randint(0, 999999)
        # ?
        logger.info(sms_code)

        # 多个redis.setex， 可使用管道执行优化速度
        # 创建管道对象
        pl = redis_conn.pipeline()
        # 2.保存到缓存中, 以备后续校验
        # redis_conn.setex('sms_%s' % mobile, 60, sms_code)
        # 加入到管道队列
        pl.setex('sms_%s' % mobile, 60, sms_code)

        # 保存一个已发短信手机的flag
        pl.setex('flag_%s' % mobile, 60, 1)
        # 执行管道
        pl.execute()
        # 3.发送短信给mobile (手机号, [验证码data, 提示分钟], 模板ID)
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # CCP发短信会有延迟阻塞，可以用多进程去异步执行，这里可以用celery技术
        send_sms_code.delay(mobile, sms_code)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信成功'})



